package pl.edu.mimuw.mas.agent;

import jade.content.lang.Codec;
import jade.content.lang.sl.SLCodec;
import jade.content.onto.Ontology;
import jade.core.AID;
import jade.core.Agent;
import jade.domain.DFService;
import jade.domain.FIPAException;
import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.SearchConstraints;
import jade.domain.FIPAAgentManagement.ServiceDescription;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import pl.edu.mimuw.mas.ontology.VisualizationCoreOntology;

/**
 * Abstrakcyjny klient, metoda <code>setServiceAgents</code> ustawia standartowe
 * usługi i powinna być wykonywana dla każdego agenta podczas inicjalizacji.
 */
@SuppressWarnings("serial") // Abstrakcjyjna klasa
public abstract class ClientAgent extends Agent {

	private final Codec codec = new SLCodec();
	private final Ontology viz3DOntology = VisualizationCoreOntology.getInstance();

	private AID viz2DAgent;
	private AID viz3DAgent;
	private AID logAgent;

	private Logger logger = LoggerFactory.getLogger(getClass());

	protected void setLanguages() {
		getContentManager().registerLanguage(codec);
		getContentManager().registerOntology(viz3DOntology);		
	}

	protected boolean setServiceAgents() {
  		DFAgentDescription tpl = new DFAgentDescription();
  		ServiceDescription srvspl = new ServiceDescription();
  		tpl.addServices(srvspl);

  		SearchConstraints sc = new SearchConstraints();
  		sc.setMaxResults(new Long(1));
  		  		
  		DFAgentDescription[] results;
		try {
	  		// Wizualizacja 2D
			logger.info("{} : szukam dostawcy usługi {}", getName(), Visualization2DAgent.SERVICE_TYPE);
	  		srvspl.setType(Visualization2DAgent.SERVICE_TYPE);

			results = DFService.search(this, tpl, sc);
	  		if (results.length > 0) {
	  			viz2DAgent = results[0].getName();
	  			logger.info("{} : znalazłem agenta {}", getName(), viz2DAgent.getName());
	  		} else {
	  			logger.info("{} : nie znalazłem szukanego agenta", getName());
	  			return false;
	  		}
	  		
			// Wizualizacja 3D
			logger.info("{} : szukam dostawcy usługi {}", getName(), Visualization3DAgent.SERVICE_TYPE);
	  		srvspl.setType(Visualization3DAgent.SERVICE_TYPE);

			results = DFService.search(this, tpl, sc);
	  		if (results.length > 0) {
	  			viz3DAgent = results[0].getName();
	  			logger.info("{} : znalazłem agenta {}", getName(), viz3DAgent.getName());
	  		} else {
	  			logger.info("{} : nie znalazłem szukanego agenta", getName());
	  			return false;
	  		}
	  		
	  		// Logowanie
			logger.info("{} : szukam dostawcy usługi {}", getName(), LogAgent.SERVICE_TYPE);
	  		srvspl.setType(LogAgent.SERVICE_TYPE);

			results = DFService.search(this, tpl, sc);
	  		if (results.length > 0) {
	  			logAgent = results[0].getName();
	  			logger.info("{} : znalazłem agenta {}", getName(), logAgent.getName());
	  		} else {
	  			logger.info("{} : nie znalazłem szukanego agenta", getName());
	  			return false;
	  		}
		} catch (FIPAException e) {
			logger.error("{} : błąd FIPA", getName(), e);
			return false;
		}

  		return true;
	}
	
	public AID getViz2DAgent() {
		return this.viz2DAgent;
	}
	
	public AID getViz3DAgent() {
		return this.viz3DAgent;
	}

	public AID getLogAgent() {
		return this.logAgent;
	}
}
